package zhouyang.syncup;

import lombok.Synchronized;
import org.openjdk.jol.info.ClassLayout;

import java.util.concurrent.TimeUnit;

/**
 * @author: 叶子
 * @date: 2022/06/14 23:03
 * 偏向锁无实际竞争，对象头存储的是线程id
 * 轻量级锁存储指向栈帧中lock Record的指针
 * 重量级锁存储指向堆中互斥量的指针
 * 轻量级锁自旋，jdk1.6之后是自适应自旋，1.6之前是固定自旋10次不成功升级成重量级锁
 * 偏向锁无法保存hashcode，轻量级锁和重量级锁可以
 **/
public class SynchronizedUpDemo {
    /**
     * 演示偏向锁的情况下，调用了hashcode()方法，偏向锁升级为轻量级锁或重量级锁
     */
    public static void main(String[] args) {
        //先睡眠5秒，保证开启偏向锁
        try {
            TimeUnit.SECONDS.sleep(5);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("本应是偏向锁101");
        Object o = new Object();
        synchronized (o){
            o.hashCode();
            System.out.println("偏向锁过程中遇到一致性哈希计算请求，立马撤销偏向锁，膨胀为重量级锁10");
            System.out.println(ClassLayout.parseInstance(o).toPrintable());
        }
    }

    private static void p2q() {
        //先睡眠5秒，保证开启偏向锁
        try {
            TimeUnit.SECONDS.sleep(5);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        Object o = new Object();
        System.out.println("本应是偏向锁101");
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
        o.hashCode();
        /**没有重写，一致性哈希，重写后无效，当一个对象已经计算过identity hashcode，无法进入偏向锁状态
         *但是如果这里直接调用 System.out.println(ClassLayout.parseInstance(o).toPrintable());
         * 得到的是无锁状态
         */
        synchronized (o){
        System.out.println("本应是偏向锁，但是由于计算过一致性哈希，会直接升级为轻量级锁00");
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
        //这里面会打印出轻量级锁00
        }
    }
}